#! /usr/bin/env python
#coding=utf-8

#from utils import command
import cxxfilt

# https://subscription.packtpub.com/book/networking-and-servers/9781782167105/2/ch02lvl1sec15/elf-symbols

class Symbol(dict):
	def __init__(self, name, version, library, weak):
		self["name"] = name
		self["version"] = version
		self["library"] = library
		self["weak"] = weak
		try:
			self["demangle"] = self.demangle()
		except:
			self["demangle"] = self["name"]
		self["calls"] = 0

	def __str__(self):
		ret = [self.name]
		if self.version:
			ret.append(self.version)
			if self.library:
				ret.append(self.library)
		return '@'.join(ret)

	def demangle(self):
		#output = command("c++filt " + self["name"])
		return cxxfilt.demangle(self["name"])

class UndefinedSymbol(Symbol):
	def __init__(self, name, weak, version, library):
		super(UndefinedSymbol, self).__init__(name, version, library, weak)
		self["library"] = library

	def set_idx(self, idx):
		self["id"] = idx

class ProvidedSymbol(Symbol):
	def __init__(self, name, version, library, default_version, idx):
		super(ProvidedSymbol, self).__init__(name, version, library, False)
		self["default_version"] = default_version
		self["weak"] = False
		self["id"] = idx

	def base_names(self):
		ret = []

		if self.version:
			if self.library:
				ret.append('@'.join((self.name, self.version, self.library)))

			ret.append('@'.join((self.name, self.version)))

			if self.default_version:
				ret.append(self.name)

		else:
			ret.append(self.name)

		return ret

	def linker_name(self):
		if self.default_version or not self.version:
			return self.name

		return '@'.join((self.name, self.version))

if __name__ == '__main__':
	def test_demangle(name):
		try:
			res = cxxfilt.demangle(name)
		except:
			res = name
		return res

	print(test_demangle("_ZTVNSt3__h14basic_ifstreamIcNS_11char_traitsIcEEEE"))
